package com.lancoo.dictionary.activity;

import android.content.Context;
import android.content.Intent;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnPreparedListener;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.CardView;
import android.support.v7.widget.RecyclerView;
import android.text.TextUtils;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.view.View.OnKeyListener;
import android.view.WindowManager;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.TextView;

import com.google.gson.Gson;
import com.lancoo.dictionary.DictionaryHelper;
import com.lancoo.dictionary.R;
import com.lancoo.dictionary.data.adapter.SearchHistoryAdapter;
import com.lancoo.dictionary.data.adapter.SearchResultAdapter;
import com.lancoo.dictionary.data.model.DicSearchBehavior;
import com.lancoo.dictionary.data.model.SearchHistory;
import com.lancoo.dictionary.data.model.Vocabulary;
import com.lancoo.dictionary.nc.NetworkConnection;
import com.lancoo.dictionary.utils.DitchItemDecoration;
import com.lancoo.dictionary.utils.KeyBoardUtils;
import com.lancoo.dictionary.widget.QuickclearEditText;
import com.lancoo.dictionary.widget.QuickclearEditText.InputChangedListenner;

import org.xutils.DbManager;
import org.xutils.common.Callback.CommonCallback;
import org.xutils.ex.DbException;

import java.util.Date;
import java.util.List;

/**
 * 
 * Copyright (C) 2016 LANCOO. All Rights Reserved.
 *
 * @author 刘孟孟 2016年5月17日
 */
public class DictionaryActicity extends AppCompatActivity implements InputChangedListenner, CommonCallback<String>,
		OnPreparedListener, OnItemClickListener, OnKeyListener {
	
	public static final String KEY_PRECONTENT= "preContent";
	public static final String KEY_API_PATH= "apiPath";
	public static final String KEY_RES_BASEURL= "resBaseUrl";
	public static final String KEY_SHOW_BACK_BTN= "showBackBtn";

	private QuickclearEditText searchBox;
	private TextView searchCommand;
	private ListView searchHistoryLv;
	private RecyclerView searchResultRv;

	private DbManager dbManager;
	private Vocabulary vocabulary;
	private MediaPlayer mediaPlayer;
	private SearchResultAdapter searchResultAdapter;
	private SearchHistoryAdapter searchHistoryAdapter;

	private ProgressBar progressBar;
	private CardView dicNoticeCv;
	private TextView dicNotice;

	private NetworkConnection curConnection;

	public void onClick(View v) {
		if (v.getId()==R.id.dic_search_command){
			if (getString(R.string.lcdic_cancel).equals(searchCommand.getText())) {
				finish();
			} else {
				goSearch();
			}
		}else if(v.getId()==R.id.dic_back_btn){
			finish();
		}
	}

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		if (savedInstanceState != null) {
			DictionaryHelper.API_PATH = savedInstanceState.getString(KEY_API_PATH);
			DictionaryHelper.RES_BASE_URL = savedInstanceState.getString(KEY_RES_BASEURL);
			DictionaryHelper.SHOW_BACK_BTN =savedInstanceState.getBoolean(KEY_SHOW_BACK_BTN);
		}
		setContentView(R.layout.lcdic_activty_dictionary);
		findViewById(R.id.dic_back_btn).setVisibility(DictionaryHelper.SHOW_BACK_BTN?View.VISIBLE:View.GONE);
		searchBox = (QuickclearEditText) findViewById(R.id.dic_search_box);
		searchCommand = (TextView) findViewById(R.id.dic_search_command);
		searchHistoryLv = (ListView) findViewById(R.id.dic_search_history);
		searchResultRv = (RecyclerView) findViewById(R.id.dic_search_result_rv);
		progressBar = (ProgressBar) findViewById(R.id.dic_progressbar);
		dicNoticeCv = (CardView) findViewById(R.id.dic_notice_cv);
		dicNotice = (TextView) findViewById(R.id.dic_notice);
		searchHistoryLv.setOnItemClickListener(this);
		searchBox.setOnKeyListener(this);

		searchResultRv.addItemDecoration(new DitchItemDecoration(12f));
		searchBox.setInputChangedListenner(this);
		mediaPlayer = new MediaPlayer();
		mediaPlayer.setOnPreparedListener(this);
		dbManager = DictionaryHelper.getDbManager();

		Intent intent = getIntent();
		String preContent = intent.getStringExtra(KEY_PRECONTENT);
		if (TextUtils.isEmpty(preContent)) {
			loadSearchHistories(null);
		}else{
			try {
				autoSearch(preContent);
			} catch (DbException e) {
				e.printStackTrace();
			}
		}
	}

	private void loadSearchHistories(CharSequence input) {
		if (dbManager==null) return;
		List<SearchHistory> searchHistories = null;
		if (TextUtils.isEmpty(input)) {
			try {
				searchHistories = dbManager.selector(SearchHistory.class).orderBy("searchDate", true).findAll();
			} catch (DbException e) {
				e.printStackTrace();
			}
		} else {
			try {
				searchHistories = dbManager.selector(SearchHistory.class).where("searchContent", "LIKE", input + "%")
						.findAll();
			} catch (DbException e) {
				e.printStackTrace();
			}
		}
		if (searchHistories==null) {
			return;
		}
		if (searchHistoryAdapter == null) {
			searchHistoryAdapter = new SearchHistoryAdapter(searchHistories);
			searchHistoryLv.setAdapter(searchHistoryAdapter);
		} else {
			searchHistoryAdapter.updateDataSet(searchHistories);
		}
	}

	@Override
	protected void onSaveInstanceState(Bundle outState) {
		outState.putString(KEY_API_PATH, DictionaryHelper.API_PATH);
		outState.putString(KEY_RES_BASEURL, DictionaryHelper.RES_BASE_URL);
		outState.putBoolean(KEY_SHOW_BACK_BTN,DictionaryHelper.SHOW_BACK_BTN);
		super.onSaveInstanceState(outState);
	}

	/**
	 * InputChangedListenner from QuickclearEditText
	 */
	@Override
	public void onInputChanged(boolean hasInput, CharSequence input) {
		searchCommand.setText(hasInput ? R.string.lcdic_search : R.string.lcdic_cancel);
		if (curConnection != null) {
			curConnection.cancelConnection();
		}
		dicNoticeCv.setVisibility(View.GONE);
		searchResultRv.setVisibility(View.GONE);
		progressBar.setVisibility(View.GONE);
		searchHistoryLv.setVisibility(View.VISIBLE);
		loadSearchHistories(input);
	}

	/**
	 * networkConnection callback region
	 */
	@Override
	public void onSuccess(String result) {
		vocabulary = new Gson().fromJson(result, Vocabulary.class);
		try {
			if (vocabulary!=null) {
				if (dbManager!=null){
					dbManager.saveOrUpdate(new SearchHistory(vocabulary.getCwName(), new Date(),result));
				}
			}
		} catch (DbException e) {
			e.printStackTrace();
		}
		showSearchResult();
	}

	@Override
	public void onError(Throwable ex, boolean isOnCallback) {
		Log.e("dic_http",ex.getMessage());
		ex.printStackTrace();
		showNotice(R.string.lcdic_search_failed);
	}

	@Override
	public void onCancelled(CancelledException cex) {
	}

	@Override
	public void onFinished() {
		progressBar.setVisibility(View.GONE);
		DictionaryHelper.sendDicSearchBroadcast(this,searchBox.getRealInput(), DicSearchBehavior.SOURCE_HTTP,vocabulary!=null&&vocabulary.getCwName().equals(searchBox.getRealInput()));
	}

	/**
	 * networkConnection callback region
	 */

	private void goSearch() {
		KeyBoardUtils.closeKeybord(this);
		dicNoticeCv.setVisibility(View.GONE);
		searchHistoryLv.setVisibility(View.GONE);
		searchResultRv.setVisibility(View.GONE);
		progressBar.setVisibility(View.VISIBLE);
		String knowlegde = searchBox.getRealInput();
		curConnection = new NetworkConnection(knowlegde, this);
	}

	private void showSearchResult() {
		if (vocabulary == null || vocabulary.getCxCollection() == null) {//修复bug by TML
			showNotice(R.string.lcdic_search_failed);
			return;
		}
		searchResultRv.setVisibility(View.VISIBLE);
		if (searchResultAdapter == null) {
			searchResultAdapter = new SearchResultAdapter(vocabulary, mediaPlayer);
			searchResultRv.setAdapter(searchResultAdapter);
		} else {
			searchResultRv.smoothScrollToPosition(0);
			searchResultAdapter.updateData(vocabulary);
		}
	}
	
	private void showSearchResultFromDB(){
		KeyBoardUtils.closeKeybord(this);
		dicNoticeCv.setVisibility(View.GONE);
		progressBar.setVisibility(View.GONE);
		searchHistoryLv.setVisibility(View.GONE);
		String knowlegde = searchBox.getRealInput();
		try {
			SearchHistory searchHistory=dbManager.findById(SearchHistory.class, knowlegde);
			vocabulary = new Gson().fromJson(searchHistory.getMeaning(), Vocabulary.class);
			searchResultRv.setVisibility(View.VISIBLE);
			if (searchResultAdapter == null) {
				searchResultAdapter = new SearchResultAdapter(vocabulary, mediaPlayer);
				searchResultRv.setAdapter(searchResultAdapter);
			} else {
				searchResultRv.smoothScrollToPosition(0);
				searchResultAdapter.updateData(vocabulary);
			}
		} catch (DbException e) {
			e.printStackTrace();
		}finally {
			if (vocabulary==null) return;
			DictionaryHelper.sendDicSearchBroadcast(this,vocabulary.getCwName(), DicSearchBehavior.SOURCE_DB,true);
		}
	}
	
	private void autoSearch(String searchContent) throws DbException{
		searchBox.setText(searchContent);
		searchBox.setSelection(searchContent.length());
		getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN
                | WindowManager.LayoutParams.SOFT_INPUT_ADJUST_UNSPECIFIED);
		dicNoticeCv.setVisibility(View.GONE);
		searchHistoryLv.setVisibility(View.GONE);
		String knowlegde = searchBox.getRealInput();
		SearchHistory searchHistory=dbManager==null?null:dbManager.findById(SearchHistory.class, knowlegde);
		if (searchHistory!=null) {
			progressBar.setVisibility(View.GONE);
			searchResultRv.setVisibility(View.VISIBLE);
			vocabulary = new Gson().fromJson(searchHistory.getMeaning(), Vocabulary.class);
			if (searchResultAdapter == null) {
				searchResultAdapter = new SearchResultAdapter(vocabulary, mediaPlayer);
				searchResultRv.setAdapter(searchResultAdapter);
			} else {
				searchResultRv.smoothScrollToPosition(0);
				searchResultAdapter.updateData(vocabulary);
			}
			DictionaryHelper.sendDicSearchBroadcast(this,vocabulary.getCwName(), DicSearchBehavior.SOURCE_DB,true);
		}else{
			progressBar.setVisibility(View.VISIBLE);
			searchResultRv.setVisibility(View.GONE);
			curConnection = new NetworkConnection(knowlegde, this);
		}
	}

	private void showNotice(String notice) {
		dicNoticeCv.setVisibility(View.VISIBLE);
		dicNotice.setText(notice);
	}

	private void showNotice(int noticeResId) {
		dicNoticeCv.setVisibility(View.VISIBLE);
		dicNotice.setText(noticeResId);
	}

	@Override
	protected void onPause() {
		super.onPause();
		if (mediaPlayer != null && mediaPlayer.isPlaying()) {
			mediaPlayer.pause();
		}
	}

	@Override
	protected void onDestroy() {
		super.onDestroy();
		if (mediaPlayer != null) {
			mediaPlayer.release();
			mediaPlayer = null;
		}
	}

	@Override
	public void onPrepared(MediaPlayer mp) {
		mp.start();
	}

	@Override
	public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
		SearchHistory searchHistory = (SearchHistory) parent.getItemAtPosition(position);
		String searchContent = searchHistory.getSearchContent();
		searchBox.setText(searchContent);
		searchBox.setSelection(searchContent.length());
		showSearchResultFromDB();

	}

	@Override
	public boolean onKey(View v, int keyCode, KeyEvent event) {
		if (keyCode == KeyEvent.KEYCODE_ENTER) {
			if (searchBox.getRealInput().length() > 0) {
				goSearch();
			}
			return true;
		}
		return false;
	}

	public static void startWithContent(Context context, String preContent){
		Intent intent = new Intent(context, DictionaryActicity.class);
		intent.putExtra(KEY_PRECONTENT, preContent);
		intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
		context.startActivity(intent);
	}


}
